#include <csapp.h>
#include <cstdio>
#include <cstdlib>
#include <pthread.h>
#include <semaphore.h>

#define MAXTHREAD 32

void *sum_mutext(void *);
long psum[MAXTHREAD];
long nelems_per_pthread;

sem_t mutex;

int main(int argc, char* argv[]) {
    long i, nelem, log_nelems, nthreads, myid[MAXTHREAD];
    pthread_t tid[MAXTHREAD];

    if (argc != 3) {
	fprintf(stderr, "Usage: %s <nthreads> <log_nelems>\n", argv[0]);
	return -1;
    }
    nthreads = atoi(argv[1]);
    log_nelems = atoi(argv[2]);
    nelem = (1L << log_nelems);
    nelems_per_pthread = nelem / nthreads;
    sem_init(&mutex, 0, 1);

    for (i = 0; i < nthreads; ++ i) {
	myid[i] = i;
	Pthread_create(&tid[i], NULL, sum_mutext, &myid[i]);
    }

    for (i = 0; i < nthreads; ++i) {
	Pthread_join(tid[i], NULL);
    }
    
    long gsum = 0;
    for (i = 0; i < MAXTHREAD; ++ i ) {
	gsum += psum[i];
    }
    if (gsum != (nelem * (nelem - 1) / 2)) {
	printf("Error: result = %ld\n", gsum);
    }else {
	printf("Get resulr = [%ld]\n", gsum);
    }

    return 0;
}

void *sum_mutext(void* args) {
    long myid = *((long *)args);
    long start = myid * nelems_per_pthread;
    long end = start + nelems_per_pthread;
    long sum = 0;

    for (long i = start; i < end; ++i) {
	sum += i;
    }
    psum[myid] = sum;

    return NULL;
}
